// 简易图片懒加载与失败兜底指令
// 用法：
// <img v-lazy="{ src: imageUrl, fallback: fallbackUrl }" alt="..." />
// 也支持传入字符串：<img v-lazy="imageUrl" />

function resolveBinding(value) {
  if (typeof value === 'string') {
    return { src: value, fallback: null }
  }
  const v = value || {}
  return { src: v.src, fallback: v.fallback || null }
}

function loadImage(el, src, fallback) {
  if (!src) return
  const onError = () => {
    if (fallback) {
      el.src = fallback
    }
    el.classList.add('is-error')
  }
  const onLoad = () => {
    el.classList.add('is-loaded')
    el.removeEventListener('error', onError)
    el.removeEventListener('load', onLoad)
  }
  el.addEventListener('error', onError)
  el.addEventListener('load', onLoad)
  el.src = src
}

function createObserver(el, src, fallback) {
  const io = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        loadImage(el, src, fallback)
        io.unobserve(el)
      }
    })
  }, { rootMargin: '0px', threshold: 0.1 })
  io.observe(el)
  return io
}

export default {
  mounted(el, binding) {
    const { src, fallback } = resolveBinding(binding.value)
    // 设置占位，避免破图图标
    el.src = ''
    el.__lazyObserver = createObserver(el, src, fallback)
  },
  updated(el, binding) {
    const { src, fallback } = resolveBinding(binding.value)
    // 若源变更，重新监听
    if (el.__lazyObserver) {
      el.__lazyObserver.disconnect()
    }
    el.__lazyObserver = createObserver(el, src, fallback)
  },
  unmounted(el) {
    if (el.__lazyObserver) {
      el.__lazyObserver.disconnect()
      el.__lazyObserver = null
    }
  }
}